<html>
<head><meta charset="utf-8"><title>Is there any better way to write this code? · general · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/index.html">general</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Is.20there.20any.20better.20way.20to.20write.20this.20code.3F.html">Is there any better way to write this code?</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="160212824"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Is%20there%20any%20better%20way%20to%20write%20this%20code%3F/near/160212824" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gfreezy <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Is.20there.20any.20better.20way.20to.20write.20this.20code.3F.html#160212824">(Mar 07 2019 at 16:24)</a>:</h4>
<div class="codehilite"><pre><span></span>fn decode_message&lt;T: Read&gt;(
    tree: &amp;mut MessageTree,
    transaction: Option&lt;&amp;mut InnerTransaction&gt;,
    buf: &amp;mut T,
) -&gt; Fallible&lt;()&gt; {

    match transaction {
        None =&gt; {
            let mut chs = [0];
            loop {
                let size = buf.read(&amp;mut chs)?;
                if size == 0 {
                    break;
                }
                let ch = chs[0];

                match dbg!(ch) {
                    b&#39;t&#39; =&gt; decode_transaction(tree, None, buf)?,
                    b&#39;T&#39; =&gt; return Ok(()),
                    b&#39;E&#39; =&gt; decode_event(tree, None, buf)?,
                    b&#39;M&#39; =&gt; decode_metric(tree, None, buf)?,
                    b&#39;H&#39; =&gt; decode_heartbeat(tree, None, buf)?,
                    b&#39;L&#39; =&gt; decode_trace(tree, None, buf)?,
                    _ =&gt; unimplemented!(&quot;unsupported type&quot;),
                }
            }
        },
        Some(transaction) =&gt; {
            let mut chs = [0];
            loop {
                let size = buf.read(&amp;mut chs)?;
                if size == 0 {
                    break;
                }
                let ch = chs[0];

                match dbg!(ch) {
                    b&#39;t&#39; =&gt; decode_transaction(tree, Some(transaction), buf)?,
                    b&#39;T&#39; =&gt; return Ok(()),
                    b&#39;E&#39; =&gt; decode_event(tree, Some(transaction), buf)?,
                    b&#39;M&#39; =&gt; decode_metric(tree, Some(transaction), buf)?,
                    b&#39;H&#39; =&gt; decode_heartbeat(tree, Some(transaction), buf)?,
                    b&#39;L&#39; =&gt; decode_trace(tree, Some(transaction), buf)?,
                    _ =&gt; unimplemented!(&quot;unsupported type&quot;),
                }
            }
        }
    }

    Ok(())
}
</pre></div>



<a name="160213965"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Is%20there%20any%20better%20way%20to%20write%20this%20code%3F/near/160213965" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Is.20there.20any.20better.20way.20to.20write.20this.20code.3F.html#160213965">(Mar 07 2019 at 16:36)</a>:</h4>
<p>You could replace the entire <code>match transaction</code> with </p>
<div class="codehilite"><pre><span></span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">chs</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="mi">0</span><span class="p">];</span><span class="w"></span>
<span class="w">            </span><span class="k">loop</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">                </span><span class="kd">let</span><span class="w"> </span><span class="n">size</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">buf</span><span class="p">.</span><span class="n">read</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="n">chs</span><span class="p">)</span><span class="o">?</span><span class="p">;</span><span class="w"></span>
<span class="w">                </span><span class="k">if</span><span class="w"> </span><span class="n">size</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">                    </span><span class="k">break</span><span class="p">;</span><span class="w"></span>
<span class="w">                </span><span class="p">}</span><span class="w"></span>
<span class="w">                </span><span class="kd">let</span><span class="w"> </span><span class="n">ch</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">chs</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span><span class="w"></span>

<span class="w">                </span><span class="k">match</span><span class="w"> </span><span class="n">dbg</span><span class="o">!</span><span class="p">(</span><span class="n">ch</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">                    </span><span class="sc">b&#39;t&#39;</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="n">decode_transaction</span><span class="p">(</span><span class="n">tree</span><span class="p">,</span><span class="w"> </span><span class="n">transaction</span><span class="p">,</span><span class="w"> </span><span class="n">buf</span><span class="p">)</span><span class="o">?</span><span class="p">,</span><span class="w"></span>
<span class="w">                    </span><span class="sc">b&#39;T&#39;</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nb">Ok</span><span class="p">(()),</span><span class="w"></span>
<span class="w">                    </span><span class="sc">b&#39;E&#39;</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="n">decode_event</span><span class="p">(</span><span class="n">tree</span><span class="p">,</span><span class="w"> </span><span class="n">transaction</span><span class="p">,</span><span class="w"> </span><span class="n">buf</span><span class="p">)</span><span class="o">?</span><span class="p">,</span><span class="w"></span>
<span class="w">                    </span><span class="sc">b&#39;M&#39;</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="n">decode_metric</span><span class="p">(</span><span class="n">tree</span><span class="p">,</span><span class="w"> </span><span class="n">transaction</span><span class="p">,</span><span class="w"> </span><span class="n">buf</span><span class="p">)</span><span class="o">?</span><span class="p">,</span><span class="w"></span>
<span class="w">                    </span><span class="sc">b&#39;H&#39;</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="n">decode_heartbeat</span><span class="p">(</span><span class="n">tree</span><span class="p">,</span><span class="w"> </span><span class="n">transaction</span><span class="p">,</span><span class="w"> </span><span class="n">buf</span><span class="p">)</span><span class="o">?</span><span class="p">,</span><span class="w"></span>
<span class="w">                    </span><span class="sc">b&#39;L&#39;</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="n">decode_trace</span><span class="p">(</span><span class="n">tree</span><span class="p">,</span><span class="w"> </span><span class="n">transaction</span><span class="p">,</span><span class="w"> </span><span class="n">buf</span><span class="p">)</span><span class="o">?</span><span class="p">,</span><span class="w"></span>
<span class="w">                    </span><span class="n">_</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="n">unimplemented</span><span class="o">!</span><span class="p">(</span><span class="s">&quot;unsupported type&quot;</span><span class="p">),</span><span class="w"></span>
<span class="w">                </span><span class="p">}</span><span class="w"></span>
<span class="w">            </span><span class="p">}</span><span class="w"></span>
</pre></div>


<p>and just pass the <code>Option&lt;&amp;mut...&gt;</code> directly into your decode methods</p>



<a name="160248708"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Is%20there%20any%20better%20way%20to%20write%20this%20code%3F/near/160248708" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Is.20there.20any.20better.20way.20to.20write.20this.20code.3F.html#160248708">(Mar 07 2019 at 23:33)</a>:</h4>
<p>can they? its in a loop, that will move it (and thus it won't be available in the next loop iteration), right?</p>



<a name="160248782"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Is%20there%20any%20better%20way%20to%20write%20this%20code%3F/near/160248782" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Is.20there.20any.20better.20way.20to.20write.20this.20code.3F.html#160248782">(Mar 07 2019 at 23:34)</a>:</h4>
<p>i.e. I think one thing that may be happening is that their original code is reborrowing the <code>&amp;mut</code> underneath the option in the <code>Some</code> case, no?</p>



<a name="160248854"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Is%20there%20any%20better%20way%20to%20write%20this%20code%3F/near/160248854" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Is.20there.20any.20better.20way.20to.20write.20this.20code.3F.html#160248854">(Mar 07 2019 at 23:35)</a>:</h4>
<p>(let me double-check this claim)</p>



<a name="160249308"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Is%20there%20any%20better%20way%20to%20write%20this%20code%3F/near/160249308" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Is.20there.20any.20better.20way.20to.20write.20this.20code.3F.html#160249308">(Mar 07 2019 at 23:43)</a>:</h4>
<p>yes, here is a demonstration of what I am saying (<a href="https://play.rust-lang.org/?version=nightly&amp;mode=debug&amp;edition=2018" target="_blank" title="https://play.rust-lang.org/?version=nightly&amp;mode=debug&amp;edition=2018">play</a>): </p>
<div class="codehilite"><pre><span></span><span class="k">fn</span> <span class="nf">foo_1</span><span class="p">(</span><span class="n">arg</span>: <span class="nb">Option</span><span class="o">&lt;&amp;</span><span class="k">mut</span><span class="w"> </span><span class="n">Oops</span><span class="o">&gt;</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">match</span><span class="w"> </span><span class="n">arg</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="nb">Some</span><span class="p">(</span><span class="n">arg</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="k">loop</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">handle_arg</span><span class="p">(</span><span class="nb">Some</span><span class="p">(</span><span class="n">arg</span><span class="p">))</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="w">        </span><span class="nb">None</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="k">loop</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">handle_arg</span><span class="p">(</span><span class="nb">None</span><span class="p">)</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">fn</span> <span class="nf">foo_2</span><span class="p">(</span><span class="n">arg</span>: <span class="nb">Option</span><span class="o">&lt;&amp;</span><span class="k">mut</span><span class="w"> </span><span class="n">Oops</span><span class="o">&gt;</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">loop</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">handle_arg</span><span class="p">(</span><span class="n">arg</span><span class="p">)</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</pre></div>



<a name="160249330"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Is%20there%20any%20better%20way%20to%20write%20this%20code%3F/near/160249330" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Is.20there.20any.20better.20way.20to.20write.20this.20code.3F.html#160249330">(Mar 07 2019 at 23:43)</a>:</h4>
<p>in the above, <code>foo_1</code> compiles successfully while <code>foo_2</code> has an error, "use of moved value <code>arg</code>"</p>



<a name="160249520"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Is%20there%20any%20better%20way%20to%20write%20this%20code%3F/near/160249520" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Is.20there.20any.20better.20way.20to.20write.20this.20code.3F.html#160249520">(Mar 07 2019 at 23:47)</a>:</h4>
<p>This one works, but yuck: </p>
<div class="codehilite"><pre><span></span><span class="k">fn</span> <span class="nf">foo_3</span><span class="p">(</span><span class="k">mut</span><span class="w"> </span><span class="n">arg</span>: <span class="nb">Option</span><span class="o">&lt;&amp;</span><span class="k">mut</span><span class="w"> </span><span class="n">Oops</span><span class="o">&gt;</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">loop</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">handle_arg</span><span class="p">(</span><span class="n">arg</span><span class="p">.</span><span class="n">as_mut</span><span class="p">().</span><span class="n">map</span><span class="p">(</span><span class="o">|</span><span class="n">x</span><span class="o">|&amp;</span><span class="k">mut</span><span class="w"> </span><span class="o">**</span><span class="n">x</span><span class="p">))</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</pre></div>



<a name="160249738"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Is%20there%20any%20better%20way%20to%20write%20this%20code%3F/near/160249738" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Is.20there.20any.20better.20way.20to.20write.20this.20code.3F.html#160249738">(Mar 07 2019 at 23:50)</a>:</h4>
<p>/me wonders if this pattern occurs enough to motivate a <code>fn reborrow(&amp;mut self)</code> method on <code>Option&lt;&amp;mut T&gt;</code> and the like</p>



<a name="160258376"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Is%20there%20any%20better%20way%20to%20write%20this%20code%3F/near/160258376" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gfreezy <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Is.20there.20any.20better.20way.20to.20write.20this.20code.3F.html#160258376">(Mar 08 2019 at 02:41)</a>:</h4>
<p>This works if i changed <code> Option&lt;&amp;mut Oops&gt;</code> to <code> &amp;mut Option&lt;Oops&gt;</code></p>
<div class="codehilite"><pre><span></span><span class="k">fn</span> <span class="nf">handle_arg</span><span class="p">(</span><span class="n">arg</span>: <span class="kp">&amp;</span><span class="nc">mut</span><span class="w"> </span><span class="nb">Option</span><span class="o">&lt;</span><span class="n">Oops</span><span class="o">&gt;</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>

<span class="p">}</span><span class="w"></span>

<span class="k">fn</span> <span class="nf">foo_1</span><span class="p">(</span><span class="n">arg</span>: <span class="kp">&amp;</span><span class="nc">mut</span><span class="w"> </span><span class="nb">Option</span><span class="o">&lt;</span><span class="n">Oops</span><span class="o">&gt;</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">loop</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="n">handle_arg</span><span class="p">(</span><span class="n">arg</span><span class="p">)</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</pre></div>



<a name="160275895"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Is%20there%20any%20better%20way%20to%20write%20this%20code%3F/near/160275895" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Is.20there.20any.20better.20way.20to.20write.20this.20code.3F.html#160275895">(Mar 08 2019 at 09:40)</a>:</h4>
<p><span class="user-mention" data-user-id="200128">@gfreezy</span> yep, that's definitely nice, if it can be used. (note though that there are situations where you would't be able to do that transformation; e.g. if the <code>&amp;mut Oops</code> were coming from somewhere else and you couldn't change the spot where the original <code>Oops</code> lives to hold an <code>Option&lt;Oops&gt;</code>)</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>